# -*- coding: utf-8 -*-

from django.template.context import RequestContext
from django.shortcuts import render_to_response, redirect
from mainapp.forms import MethodForm, ClassifferLearningDataForm,\
    ClassifferTestForm, UnsupervisedDataForm
from django.forms.forms import Form
from django.forms.fields import ChoiceField, IntegerField
from mainapp import get_dm_modules, get_dm_methods_as_choices,\
    get_dm_modules_as_choices, get_dm_method_name, get_dm_module_by_indexes,\
    get_dm_module_by_name
from django.forms.widgets import HiddenInput
from django.core.urlresolvers import reverse
from mainapp.settings import CLASSIFICATION
from django.http import HttpResponse
from django.utils.http import urlencode
from mainapp.models import ClassifferLearningData, Result, UnsupervisedData
import os
from django.conf.global_settings import MEDIA_ROOT
from django.contrib import messages
from django.core.files.base import File
from django.core.files.uploadedfile import InMemoryUploadedFile,\
    SimpleUploadedFile




def methods(request, template='methods.html'):   
    
    form = MethodForm()
    
    if 'method' in request.GET:
        
        form = MethodForm(request.GET)
        if form.is_valid():
            
            method = form.cleaned_data['method']
            
            return redirect(reverse('modules')+"?method=%s"%method)
         
    
    context_instance = RequestContext(request, {'form':form})
    return render_to_response(template, context_instance=context_instance)
    

def modules(request, template='modules.html'):

    method_index = request.GET.get('method', None)
    
    if method_index is None:
        return redirect('/')

    method_index = int(method_index)
    method_name = get_dm_method_name(method_index)
    
    ModuleForm = type('ModuleForm', (Form,), {'module':ChoiceField(choices=get_dm_modules_as_choices(method_index=method_index)), 'method': IntegerField(initial=method_index, widget=HiddenInput())} )
    form = ModuleForm()
    
    
    if 'module' in request.GET:
        
        form = ModuleForm(request.GET)
        
        if form.is_valid():
            
            module = form.cleaned_data['module']
            
            parameters = "?method=%s&module=%s"%(method_index, module)
            
            if method_name == CLASSIFICATION:
                return redirect(reverse('supervised_learning')+parameters)
            else:
                return redirect(reverse('unsupervised_init')+parameters)
    
    context_instance = RequestContext(request, {'form':form})
    return render_to_response(template, context_instance=context_instance)


def supervised_learning(request, id=None, template='learning.html'):
#    import pdb;pdb.set_trace()
    
    if request.method == 'POST':
        
        form = ClassifferLearningDataForm(request.POST, request.FILES)
        
        if not len(request.FILES):
            if len(form.data['submited']):
                
                filepath = form.data['submited']
                
                form.files['file'] = SimpleUploadedFile(os.path.basename(filepath), open(filepath).read(), 'text/plain')
        
        if form.is_valid():
            
            module_name = form.cleaned_data['module']
            module = get_dm_module_by_name(module_name)[1]
#            doc_url = get_dm_module_by_name(module_name)[1]['doc_url']
            
            classifferLearning = form.save()
            parameters = classifferLearning.get_parsed()
            
            request.session['classiffer'] = module['train'](parameters)
            request.session['module'] = module
            
            return redirect(reverse('supervised_test'))
    
    
    if id is not None:
        
        classifferLearningData = ClassifferLearningData.objects.get(id=id)
        module = get_dm_module_by_name(classifferLearningData.module)
        
        if classifferLearningData.file:            
            form = ClassifferLearningDataForm(instance=classifferLearningData, initial={'submited':classifferLearningData.file.path})
        else:
            form = ClassifferLearningDataForm(instance=classifferLearningData)
        
    else:
        try:
            method_index = int(request.GET.get('method', None))
            module_index = int(request.GET.get('module', None))
        except:
            messages.info(request, 'Błędne parametry w żądaniu GET')
            return redirect('/')
        
        module = get_dm_module_by_indexes(method_index, module_index)
        
        
        form = ClassifferLearningDataForm(initial={'module':module[0]})
    
    
    context_instance = RequestContext(request, {'form':form, 'doc_url':module[1]['doc_url']})
    return render_to_response(template, context_instance=context_instance) 


def supervised_test(request, template=u'classiffer_test.html'):
    
    form = ClassifferTestForm()
    
    classiffer = request.session['classiffer']
    module = request.session['module']
    
    if module['doc_url']:
        doc_url = module['doc_url'] 
    
    
    if request.method == 'POST':
        
        form = ClassifferTestForm(request.POST)
        
        
        if form.is_valid():
            
            test_data = form.save()
            result = module['execute'](classiffer, test_data)
            
            
            result_class = Result()
            
            result_class.description = result['description']
            if result.get('image_path', None):
                result_class.image = os.path.relpath(result['image_path'], os.path.join(MEDIA_ROOT, 'images'))
            result_class.save()
            
            return redirect('dm_result', id=result_class.id)
        
    
    context_instance = RequestContext(request, {'form':form, 'doc_url':doc_url})
    return render_to_response(template, context_instance=context_instance) 

def unsupervised_init(request, id=None, template='unsupervised_attrs.html'):
    
    if request.method == 'POST':
        
        form = UnsupervisedDataForm(request.POST, request.FILES)
        
        if not len(request.FILES):
            if len(form.data['submited']):
                
                filepath = form.data['submited']
                
                form.files['file'] = SimpleUploadedFile(os.path.basename(filepath), open(filepath).read(), 'text/plain')
        
        if form.is_valid():
            
            module_name = form.cleaned_data['module']
            module = get_dm_module_by_name(module_name)[1]

            unsupervisedData = form.save()
            parameters = unsupervisedData.get_parsed()
            
            result = module['execute'](parameters)
            
            result_class = Result()
            
            result_class.description = result['description']
            if result.get('image_path', None):
                result_class.image = os.path.relpath(result['image_path'], os.path.join(MEDIA_ROOT, 'images'))
            result_class.save()
            
            return redirect('dm_result', id=result_class.id)
    
    if id is not None:
        
        unsupervisedData = UnsupervisedData.objects.get(id=id)
        module = get_dm_module_by_name(unsupervisedData.module)
        
        if unsupervisedData.file:
            form = UnsupervisedDataForm(instance=unsupervisedData, initial={'submited':unsupervisedData.file.path})
        else:
            form = UnsupervisedDataForm(instance=unsupervisedData)
        
    else:
        try:
            method_index = int(request.GET.get('method', None))
            module_index = int(request.GET.get('module', None))
        except:
            return redirect('/')
        
        module = get_dm_module_by_indexes(method_index, module_index)
    
    
        form = UnsupervisedDataForm(initial={'module':module[0]})
    
    
    context_instance = RequestContext(request, {'form':form, 'doc_url':module[1]['doc_url']})
    return render_to_response(template, context_instance=context_instance) 


def unsupervised_load(request, id):
    
    return unsupervised_init(request, id=id)
    
def supervised_load(request, id):
    
    return supervised_learning(request, id=id)

def dm_result(request, id):
    
    result_instance = Result.objects.get(pk=id)
    
    return render_to_response('result.html', context_instance=RequestContext(request, {'result':result_instance}))


